#include <gpio.h>

#if GPIO_EN

void gpio_mode(uint8_t pin, gpio_type mode)
{
	uint8_t pin_num;
	uint8_t m1_flg, m1_val, m0_flg, m0_val;
	uint8_t xdata *PULLUP_RG;

	pin_num = pin % 10;
	PULLUP_RG = 0xfe10 + (pin / 10);

	m0_val = 1 << pin_num;
	m1_val = m0_val;

	m0_flg = mode & 0x01;
	m1_flg = mode & 0x02;

	if (m0_flg == 0)
		m0_val = ~m0_val;
	if (m1_flg == 0)
		m1_val = ~m1_val;

	switch (pin / 10)
	{
	case 0:
		if (m1_flg)
			P0M1 |= m1_val;
		else
			P0M1 &= m1_val;

		if (m0_flg)
			P0M0 |= m0_val;
		else
			P0M0 &= m0_val;
		break;
	case 1:
		if (m1_flg)
			P1M1 |= m1_val;
		else
			P1M1 &= m1_val;

		if (m0_flg)
			P1M0 |= m0_val;
		else
			P1M0 &= m0_val;
		break;
	case 2:
		if (m1_flg)
			P2M1 |= m1_val;
		else
			P2M1 &= m1_val;

		if (m0_flg)
			P2M0 |= m0_val;
		else
			P2M0 &= m0_val;
		break;
	case 3:
		if (m1_flg)
			P3M1 |= m1_val;
		else
			P3M1 &= m1_val;

		if (m0_flg)
			P3M0 |= m0_val;
		else
			P3M0 &= m0_val;
		break;
	case 4:
		if (m1_flg)
			P4M1 |= m1_val;
		else
			P4M1 &= m1_val;

		if (m0_flg)
			P4M0 |= m0_val;
		else
			P4M0 &= m0_val;
		break;
	case 5:
		if (m1_flg)
			P5M1 |= m1_val;
		else
			P5M1 &= m1_val;

		if (m0_flg)
			P5M0 |= m0_val;
		else
			P5M0 &= m0_val;
		break;
	case 6:
		if (m1_flg)
			P6M1 |= m1_val;
		else
			P6M1 &= m1_val;

		if (m0_flg)
			P6M0 |= m0_val;
		else
			P6M0 &= m0_val;
		break;
	case 7:
		if (m1_flg)
			P7M1 |= m1_val;
		else
			P7M1 &= m1_val;

		if (m0_flg)
			P7M0 |= m0_val;
		else
			P7M0 &= m0_val;
		break;
	default:
		break;
	}
	P_SW2 |= 0X80;
	m1_val = 1 << pin_num;
	if (mode == OUTPUT_PULLUP || mode == INPUT_PULLUP)
		*PULLUP_RG |= m1_val;
	else
		*PULLUP_RG &= ~m1_val;
	P_SW2 &= 0x7f;
}

void gpio_mode_all(GPIO_TYPE PIN_ALL, uint8_t flg_val, gpio_type mode)
{
	uint8_t i;
	if (PIN_ALL > 7)
		return;
	PIN_ALL *= 10;
	for (i = 0; i < 8; i++)
	{
		if (flg_val & 0x1)
		{
			gpio_mode(PIN_ALL++, mode);
		}
		flg_val >>= 1;
	}
}

void gpio_write(uint8_t pin, uint8_t level)
{
	uint8_t tmp;
	tmp = 1 << (pin % 10);
	if (!level)
		tmp = ~tmp;
	switch (pin / 10)
	{
	case 0:
		if (level)
			P0 |= tmp;
		else
			P0 &= tmp;
		break;
	case 1:
		if (level)
			P1 |= tmp;
		else
			P1 &= tmp;
		break;
	case 2:
		if (level)
			P2 |= tmp;
		else
			P2 &= tmp;
		break;
	case 3:
		if (level)
			P3 |= tmp;
		else
			P3 &= tmp;
		break;
	case 4:
		if (level)
			P4 |= tmp;
		else
			P4 &= tmp;
		break;
	case 5:
		if (level)
			P5 |= tmp;
		else
			P5 &= tmp;
		break;
	case 6:
		if (level)
			P6 |= tmp;
		else
			P6 &= tmp;
		break;
	case 7:
		if (level)
			P7 |= tmp;
		else
			P7 &= tmp;
		break;

	default:
		break;
	}
}

uint8_t gpio_read(uint8_t pin)
{
	uint8_t tmp;
	switch (pin / 10)
	{
	case 0:
		tmp = P0;
		break;
	case 1:
		tmp = P1;
		;
		break;
	case 2:
		tmp = P2;
		break;
	case 3:
		tmp = P3;
		break;
	case 4:
		tmp = P4;
		break;
	case 5:
		tmp = P5;
		break;
	case 6:
		tmp = P6;
		break;
	case 7:
		tmp = P7;
		break;
	default:
		return 0;
		break;
	}
	return (tmp >> (pin % 10)) & 1;
}
void gpio_toggle(uint8_t pin)
{
	gpio_write(pin, !gpio_read(pin));
}

#endif
